<?php
declare(strict_types=1);
/**
 * Created by PhpStorm
 * User: Administrator
 * Date: 2022/8/31
 * Time: 16:43:03
 */

namespace app\common\service\CouponService;

use app\model\BbcModel\Goods;
use app\model\BbcModel\GoodsBrand;
use app\model\BbcModel\GoodsClass;
use app\model\BbcModel\Member;
use app\model\BbcModel\StoreMember;
use app\Normal;
use app\model\BbcModel\Coupon;
use app\model\BbcModel\CouponStore;
use app\common\service\CouponService\CouponStoreService;
use app\model\BbcModel\Store;
use app\model\BbcModel\CouponManual;

class CouponService
{
    /**
     * 优惠券列表
     * @param array $param
     * @return array
     */
    public function couponLists(array $param): array
    {
        $page = (isset($param['page']) && $param['page'] != '') ? $param['page'] : 1;
        $limit = (isset($param['limit']) && $param['limit'] != '') ? $param['limit'] : 20;

        $where = [
            ['cid','=',$param['cid']],
            ['df','=',0],
        ];
        if(isset($param['name']) && $param['name'] != ''){
            $where[] = ['name','like',"%{$param['name']}%"];
        }
        if(isset($param['status']) && $param['status'] != ''){
            $where[] = ['status','=',$param['status']];
        }
        if(isset($param['scene']) && $param['scene'] != ''){
            $where[] = ['scene','=',$param['scene']];
        }
        if(isset($param['coupon_type']) && $param['coupon_type'] != ''){
            $where[] = ['coupon_type','=',$param['coupon_type']];
        }
        $data_lists = Coupon::instance()->where($where)->limit((int) $limit)->page((int) $page)->order('cd desc')->field('id,name,is_expiration,begindate,enddate,target_type,store,cd,status,is_code,coupon_type,scene,rule_type')->select();
        foreach ($data_lists as $k=>$v){
            if($v['is_expiration'] == 1){ //无时间限制
                $data_lists[$k]['valid_time'] = '无限制';
            }else{
                $data_lists[$k]['valid_time'] = date('Y-m-d',$v['begindate']).'至'.date('Y-m-d',$v['enddate']);
            }
            $data_lists[$k]['cd'] = date('Y-m-d H:i:s',$v['cd']);
        }
        $total = Coupon::instance()->where($where)->count();
        return Normal::returnCode(Normal::SUC,'获取成功',['list'=>$data_lists,'total'=>$total]);
    }

    /**
     * 新增优惠券
     * @param array $param
     * @return array
     */
    public function addCoupon( array $param): array{
        $result = $this->coupon_validate($param);
        if($result['code'] != Normal::SUC){
            return Normal::returnCode(Normal::FAIL,$result['msg']);
        }
        if($param['coupon_type'] == 1){ //新人优惠券
            $param['rule_type'] = '';
        }
        if($param['rule_type'] == 1 && $param['scene'] != 2){
            return Normal::returnCode(Normal::FAIL,'自动发放只限线上商城');
        }
        if($param['rule_type'] == 2 && empty($param['store_num'])){
            return Normal::returnCode(Normal::FAIL,'手动发放,单店铺发放总量不能为空');
        }
        if($param['is_expiration'] == 1){ //无限制
            $param['begindate'] = '';
            $param['enddate'] = '';
            $param['status'] = 2;
        }else{
            $param['begindate'] = strtotime($param['begindate']);
            $param['enddate'] = strtotime($param['enddate']) + 86399;
            if($param['enddate'] <= time()){
                return Normal::returnCode(Normal::FAIL,'优惠券结束时间不能小于当前时间');
            }

            if($param['begindate'] <= time() && time() <= $param['enddate']){
                $param['status'] = 2;
            }else if($param['begindate'] > time()){
                $param['status'] = 1;
            }
        }
        if($param['is_addition'] == 1){ //不叠加
            $param['addition'] = 1;
        }else{
            if(!isset($param['addition'])){
                return Normal::returnCode(Normal::FAIL,'请选择需要叠加的活动');
            }
            if(count($param['addition']) == 2){
                $param['addition'] = 4;
            }else if($param['addition'][0] == 3){
                $param['addition'] = 2;
            }else{
                $param['addition'] = 3;
            }
        }
        if($param['rule_type'] == 1){ //自动发放
            $param['store_num'] = 0;
        }else if($param['rule_type'] == 2){
            if(!isset($param['mn_sids']) || !$param['mn_sids']){
                return Normal::returnCode(Normal::FAIL,'手动发放优惠券必须选择店铺');
            }
        }
        if($param['activity_goods'] == 1){ //适用全场商品
            $param['type_value'] = '';
            $param['type'] = 1;
        }else{
            if(!isset($param['goods_ids'])){
                return Normal::returnCode(Normal::FAIL,'请选择指定商品');
            }
            $param['type_value'] = implode(',',$param['goods_ids']);
            $param['type'] = 2;
        }
        if(!isset($param['mn_sids']) || !$param['mn_sids']){
            $param['store'] = 1; //所有店铺
            $store_params['mn_sids'] = 0;
            $store_params['cid'] = $param['cid'];
        }else{
            $store_params['mn_sids'] = $param['mn_sids'];
            $store_params['cid'] = $param['cid'];
            $param['store'] = 2; //指定店铺
        }
        if(isset($param['explain']) && ($param['explain']) > 50){
            return Normal::returnCode(Normal::FAIL,'使用说明不能超过50字');
        }
        if($param['min_amount'] <= $param['sub_amount']){
            return Normal::returnCode(Normal::FAIL,'满减金额需大于优惠金额');
        }
        $insertData['type']          = $param['type'];
        $insertData['name']          = $param['name'];
        $insertData['explain']       = $param['explain'] ?? '';
        $insertData['is_expiration'] = $param['is_expiration'];
        $insertData['addition']      = $param['addition'];
        $insertData['min_amount']    = $param['min_amount'];
        $insertData['sub_amount']    = $param['sub_amount'];
        $insertData['rule_type']     = $param['rule_type'];
        $insertData['scene']         = $param['scene'];
        $insertData['target_type']   = $param['target_type'] ?? 0;
        $insertData['store_num']     = $param['store_num'] ?? '';
        $insertData['total']         = $param['total'] ?? 0;
        $insertData['cid']           = $param['cid'];
        $insertData['begindate']     = $param['begindate'];
        $insertData['enddate']       = $param['enddate'];
        $insertData['status']        = $param['status'];
        $insertData['type_value']    = $param['type_value'];
        $insertData['store']         = $param['store'];
        $insertData['coupon_type']   = $param['coupon_type'];
        $insertData['cd']            = time();
        Coupon::instance()->startTrans();
        try{
            $coupon_id = Coupon::instance()->insertGetId($insertData); //写入优惠券
            $store_params['coupon_id'] = $coupon_id;
            $coupon_store = new CouponStoreService();
            $res = $coupon_store->addData($store_params);
            if($res['code'] != Normal::SUC){
                throw new Exception($res['msg']); // 自定义异常信息
            }
            Coupon::instance()->commit();
        }catch (\Exception $e){
            Coupon::instance()->rollback();
            return Normal::returnCode(Normal::FAIL,$e->getMessage());
        }
        return Normal::returnCode(Normal::SUC,'新增成功');
    }

    /**
     * 优惠券详情
     * @return void
     */
    public function couponInfo( array $param): array{
        $info = Coupon::instance()->info(['cid'=>$param['cid'],'id'=>$param['id'],'df'=>0,'_fields_'=>'id,type,type_value,name,explain,is_expiration,begindate,enddate,addition,min_amount,sub_amount,rule_type,scene,store,target_type,store_num,total,coupon_type']);
        if(!$info){
            return Normal::returnCode(Normal::FAIL,'优惠券不存在');
        }
        if($info['store'] == 2){ //指定店铺
            $store_lists = CouponStore::instance()->where(['cid'=>$param['cid'],'coupon_id'=>$param['id'],'df'=>0])->column('mn_sid');
            $info['store_lists'] = $store_lists;
        }else{
            $info['store_lists'] = '';
        }
        if($info['type'] == 2){ //指定商品
            $goods_ids = explode(',',$info['type_value']);
            $goods_list = Goods::instance()->where(['cid'=>$param['cid']])->where('id','in',$goods_ids)->field('id,name,skucode,barcode,is_bonded,price,price_vip,price_market,price_cost,class_id,brand_id')->select()->toArray();
            foreach ($goods_list as $k=>$v){
                $goods_list[$k]['class_name'] = GoodsClass::instance()->info(['id'=>$v['class_id']])['name'] ?? '';
                $goods_list[$k]['brand_name'] = GoodsBrand::instance()->info(['id'=>$v['brand_id']])['name'] ?? '';
            }
            $info['goods_list'] = $goods_list;

        }else{
            $info['goods_list'] = [];
        }
        if($info['addition'] == 1){
            $info['is_addition'] = 0;//不叠加活动
        }else if($info['addition'] == 2){
            $info['is_addition'] = [3];
            $info['is_addition'] = 1;//叠加活动
        }else if($info['addition'] == 3){
            $info['is_addition'] = [4];
            $info['is_addition'] = 1;//叠加活动
        }else{
            $info['is_addition'] = 1;//叠加活动
            $info['is_addition'] = [3,4];
        }
        return Normal::returnCode(Normal::SUC,'获取成功',$info);

    }

    /**
     * 终止优惠券
     * @param array $param
     * @return array
     */
    public function changeStatus( array $param):array{
        if(!isset($param['id']) || !$param['id']){
            return Normal::returnCode(Normal::FAIL,'优惠券ID不能为空');
        }
        $info = Coupon::instance()->info(['cid'=>$param['cid'],'id'=>$param['id'],'df'=>0]);
        if(!$info){
            return Normal::returnCode(Normal::FAIL,'优惠券不存在');
        }
        if(!in_array($info['status'],[1,2])){
            return Normal::returnCode(Normal::FAIL,'当前优惠券不可结束');
        }
        $res = Coupon::instance()->edit(['id'=>$param['id']],['status'=>3]);
        if($res == false){
            return Normal::returnCode(Normal::FAIL,'操作失败');
        }
        return Normal::returnCode(Normal::SUC,'操作成功');
    }

    /**
     * 生成券编码
     * @param array $param
     * @return array
     */
    public function generateCode( array $param): array{
        $info = Coupon::instance()->info(['id'=>$param['id'],'cid'=>$param['cid'],'df'=>0]);
        if(!$info['rule_type']){
            return Normal::returnCode(Normal::FAIL,'优惠券不存在');
        }
        if($info['rule_type'] != 2){
            return Normal::returnCode(Normal::FAIL,'此优惠券不能生成券编码');
        }
        if($info['is_code'] == 2){
            return Normal::returnCode(Normal::FAIL,'此优惠券已生成券编码');
        }
        $store_lists = CouponStore::instance()->where(['cid'=>$param['cid'],'coupon_id'=>$param['id'],'df'=>0])->column('mn_sid'); //店铺

        if(!$store_lists){
            return Normal::returnCode(Normal::FAIL,'此手动发放优惠券没有店铺');
        }
        $time = time();
        $insertData = [];
        $i = 0;
        foreach ($store_lists as $k){
            $insertData[$i]['code'] = $this->create_guid($param['cid']);
            $insertData[$i]['cid'] = $param['cid'];
            $insertData[$i]['status'] = 1;
            $insertData[$i]['cd'] = $time;
            $insertData[$i]['mn_sid'] = $k;
            $insertData[$i]['coupon_id'] = $param['id'];
            $i++;
        }
        CouponManual::instance()->startTrans();
        try{
            CouponManual::instance()->insertAll($insertData);
            Coupon::instance()->where(['id'=>$param['id']])->update(['is_code'=>2]);
            CouponManual::instance()->commit();
        }catch (\ Exception $e){
            CouponManual::instance()->rollback();
            return Normal::returnCode(Normal::FAIL,$e->getMessage());
        }
        return Normal::returnCode(Normal::SUC,'操作成功');
    }

    /**
     * 券编码生成
     * @return string
     */
    public function create_guid($cid){
        $charid = uniqid((string)mt_rand(), true);
        $uuid   = $cid . substr($charid, 25, 2) . substr($charid, 1, 2) . substr($charid, 3, 3);
        return $uuid;
    }

    /**
     * 优惠券表单验证
     * @Author    Dong
     * @DateTime  2021-07-08
     * @copyright [copyright]
     * @license   [license]
     * @version   [version]
     * @param     [type]      $params [description]
     * @return    [type]              [description]
     */
    private function coupon_validate($params){
        $validate = \think\facade\Validate::rule([
            'name|优惠券名称'          => 'require',
            'coupon_type|优惠券类型'   => 'require|in:0,1',
            'is_expiration|有效期'   => 'require|number|in:1,2',
            'start_date|有效期开始日期'  => 'requireIf:is_expiration,2',
            'end_date|有效期结束日期'    => 'requireIf:is_expiration,2',
            'is_addition|优惠叠加'    => 'require',
            'min_amount|最低金额'     => 'require|float|>=:0',
            'sub_amount|优惠金额'     => 'require|float|>:0',
            'rule_type|发放类型'      => 'requireIf:coupon_type,0|in:1,2',
            'scene|活动场景'          => 'require|in:1,2,3',
            'target_type|活动用户'    => 'requireIf:coupon_type,0|in:1,2,3',
            'activity_goods|活动商品' => 'require|in:1,2',
            'goods_ids|商品'        => 'requireIf:avtivity_goods,2',
            'total|优惠券总数量'        => 'require|number|min:1'
        ]);
        if(!$validate->check($params)){
            return Normal::returnCode(Normal::FAIL,$validate->getError());
        }else{
            return Normal::returnCode(Normal::SUC);
        }
    }

    /**
     * 券编码列表
     * @param array $param
     * @return array
     */
    public function manualCouponLists( array $param): array{
        $page = (isset($param['page']) && $param['page'] != '') ? $param['page'] : 1;
        $limit = (isset($param['limit']) && $param['limit'] != '') ? $param['limit'] : 20;
        $where = [
            ['cid','=',$param['cid']],
        ];
        if(isset($param['code']) && $param['code'] != ''){
            $where[] = ['code','like',"{$param['code']}"];
        }
        if(isset($param['status']) && $param['status'] != ''){
            $where[] = ['status','=',$param['status']];
        }
        $info = Coupon::instance()->info(['id'=>$param['id'],'cid'=>$param['cid'],'df'=>0]);
        if(!$info){
            return Normal::returnCode(Normal::FAIL,'优惠券不存在');
        }
        if($info['rule_type'] != 2){
            return Normal::returnCode(Normal::FAIL,'此优惠券非手动优惠券');
        }
        if($info['is_code'] != 2){
            return Normal::returnCode(Normal::FAIL,'此优惠券未生成券编码');
        }
        $data_lists = CouponManual::instance()->where($where)->where(['coupon_id'=>$param['id']])->page((int) $page)->limit((int) $limit)->order('id desc')->field('id,code,receive_time,status,use_time')->select();
        $total = CouponManual::instance()->where(['coupon_id'=>$param['id'],'cid'=>$param['cid']])->count();
        foreach ($data_lists as $k=>$v){
            if($v['mid']){
                $data_lists[$k]['account'] = Member::instance()->info(['mid'=>$v['mid']])['account'] ?? '-';

                $data_lists[$k]['nickname'] = StoreMember::instance()->info(['mid'=>$v['mid']])['nickname'] ?? '-';
            }else{
                $data_lists[$k]['account'] = '-';
                $data_lists[$k]['nickname'] = '-';
            }
            if($v['receive_time']){
                $data_lists[$k]['receive_time'] = date('Y-m-d H:i:s',$v['receive_time']);
            }
            if($v['use_time']){
                $data_lists[$k]['use_time'] = date('Y-m-d H:i:s',$v['use_time']);
            }
        }
        return Normal::returnCode(Normal::SUC,'获取成功',['list'=>$data_lists,'total'=>$total]);
    }

    /**
     * 获取优惠券活动店铺列表
     * @param array $param
     * @return array
     */
    public function getCouponStoreLists( array $param): array{
        $page = (isset($param['page']) && $param['page'] != '') ? $param['page'] : 1;
        $limit = (isset($param['limit']) && $param['limit'] != '') ? $param['limit'] : 20;

        $info = Coupon::instance()->info(['id'=>$param['id'],'cid'=>$param['cid'],'df'=>0]);
        if(!$info){
            return Normal::returnCode(Normal::FAIL,'优惠券不存在');
        }
        if($info['store'] == 1){
            return Normal::returnCode(Normal::FAIL,'此优惠券适用于所有店铺');
        }
        $store_ids = CouponStore::instance()->where(['coupon_id'=>$info['id']])->column('mn_sid');
        if(!$store_ids){
            return Normal::returnCode(Normal::FAIL,'此优惠券未有适用于的店铺');
        }
        $store_lists = Store::instance()->where(['cid'=>$param['cid']])->where('id','in',$store_ids)->page((int) $page)->limit((int) $limit)->field('id,store_name,link_man,link_mobile,img')->order('id desc')->select();
        $total = Store::instance()->where(['cid'=>$param['cid']])->where('id','in',$store_ids)->count();
        return Normal::returnCode(Normal::SUC,'获取成功',['list'=>$store_lists,'total'=>$total]);
    }
}